import 'dart:convert';
import 'dart:io';

import 'package:args/command_runner.dart';
import 'package:sl_doclever/sl_doclever.dart';

const String argInterface = 'http';
const String argInterfaceManager = 'name';
const String argSingleton = 'singleton';
const String argMap = 'map';
const String argPrefix = 'prefix';
const String argVM = 'vm';
const String argAndroid = 'android';

class DocleverCommand extends Command {
  var prefix = '';
  bool isMap = false;
  var package = '';

  @override
  String get description => 'Doclever 接口自动化OBJC文件\n'
      '     \n支持：\n'
      '          1. 生成生成数据模型、接口管理类。\n'
      '          2. Doclever多个单接口JSON文件批量生成。\n'
      '          3. Doclever分组JSON文件批量生成。\n'
      '     \n生成接口管理类需要依赖的仓库：\n'
      '          pod \'SEGNetworkManager\'\n'
      '          pod \'SEGYYKit/SEGYYModel\'\n';

  @override
  String get name => 'doclever';

  DocleverCommand() {
    argParser.addFlag(
      argInterface,
      abbr: 'i',
      help: '生成接口管理类(默认只生成数据模型)',
      negatable: false,
    );

    argParser.addOption(
      argInterfaceManager,
      abbr: 'n',
      help: '网络请求管理类名',
    );

    argParser.addFlag(
      argMap,
      abbr: 'a',
      help: '接口参数是否为Map',
      negatable: false,
      defaultsTo: false,
    );

    argParser.addFlag(
      argSingleton,
      abbr: 's',
      help: '接口类增加单例功能',
      negatable: true,
      defaultsTo: true,
    );

    argParser.addOption(
      argPrefix,
      abbr: 'p',
      help: '文件前缀',
      defaultsTo: 'SEG',
    );

    argParser.addFlag(
      argVM,
      abbr: 'v',
      help: '生成接口请求对应的ViewModel类',
      negatable: false,
    );

    argParser.addFlag(
      argAndroid,
      abbr: 'b',
      help: '生成安卓代码,暂时只支持生成数据模型',
      negatable: false,
    );
  }

  @override
  Future run() async {
    try {
      if (argResults.rest.isEmpty) {
        printUsage();
        return;
      }

      /// 请求类是否为单例
      var isSingleTon = argParser.getDefault(argSingleton);
      if (argResults.wasParsed(argSingleton)) {
        isSingleTon = argResults[argSingleton];
      }

      /// 获取类名前缀
      prefix = argResults.wasParsed(argPrefix)
          ? argResults[argPrefix]
          : argParser.getDefault(argPrefix);

      /// 获取请求接口参数显示类型
      isMap = argResults.wasParsed(argMap)
          ? argResults[argMap]
          : argParser.getDefault(argMap);

      SLDocConfig().prefix = prefix;
      SLDocConfig().isSingleTon = isSingleTon;
      SLDocConfig().isMap = isMap;

      var outout = {};
      if (argResults.wasParsed(argAndroid)) {
        outout = outForJAVA();
      } else {
        outout = outForOBJC();
      }

      if (outout != null && outout.isNotEmpty) {
        writeToLocal(argResults.rest.first, outout);
      }
    } catch (e, s) {
      stdout.writeln('$e,$s');
    }
    return;
  }

  Map outForJAVA() {
    var outputMap = {};

    stdout.write('package name:');
    package = stdin.readLineSync();
    package = package.replaceAll(' ', '');
    if (package == null || package.isEmpty) {
      stdout.write('wrong package name');
      return outputMap;
    }

    SLDocConfig().packageName = package;

    var doc = SLDoclever(argResults.rest);
    doc.docDatas.forEach((docData) {
      outputMap.addAll(SLJava(docData).outFiles);
    });

    return outputMap;
  }

  Map outForOBJC() {
    var outputMap = {};

    /// 只生成模型
    if (!argResults.wasParsed(argInterface)) {
      var doc = SLDoclever(argResults.rest);
      doc.docDatas.forEach((docData) {
        outputMap.addAll(SLObjc(docData).toModelFiles());
      });
    } else {
      /// 生成模型、接口
      if (argResults.wasParsed(argInterfaceManager)) {
        SLDocConfig().root = argResults[argInterfaceManager];
        var doc = SLDoclever(argResults.rest);
        outputMap.addAll(SLObjcHttp(doc.docDatas).reuestMap);

        var http = SLObjcHttp(doc.docDatas);
        outputMap.addAll(http.reuestMap);
        outputMap.addAll(outForVM(http));
      } else {
        var doc = SLDoclever(argResults.rest);
        outputMap.addAll(SLObjcHttp(doc.docDatas).separateMap);
      }
    }

    return outputMap;
  }

  /// 生成接口请求对应的VM代码
  Map outForVM(SLObjcHttp http) {
    var outputMap = {};

    /// 只生成模型
    if (argResults.wasParsed(argVM)) {
      var rac = SLDocRAC(http);
      outputMap.addAll(rac.outMap);
      outputMap['${rac.racInfo.cls}_ViewModel.json'] = json.encode(rac.dataMap);
    }

    return outputMap;
  }

  Future<String> outputDir(String path) async {
    var tmpt = path.split('/').last;

    var dir = path.replaceFirst(tmpt, '');
    dir = '${dir}doclever';

    var direc = Directory(dir);

    if (await direc.exists()) {
      direc.deleteSync(recursive: true);
    }

    await direc.create();

    return direc.uri.path;
  }

  /// 把文件输出到本地
  void writeToLocal(String path, Map models) async {
    var dir = await outputDir(path);
    models.forEach((key, value) async {
      /// 输出内容
      await File(dir + key).writeAsString(value);
    });
  }
}
